package com.tongji;

import com.tongji.MyGestureDetector.OnMyGestureListener;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.inputmethod.InputMethodManager;
import android.widget.ImageView;

public class RemoteViewer extends Activity implements OnTouchListener, OnMyGestureListener {
	private CommondThread mComThread;
	private DataThread mDataThread;
	
	private boolean mStarted = false;
	private boolean mCtrlMode = false;
	private boolean mDowned = false;
	private int mMoveCount;
	
	private MyGestureDetector mGestureDetector;
	private ImageView mImageView;
	private int mViewWidth, mViewHeight;
	private int mPosX, mPosY;

	private final Handler mHandler = new Handler(Looper.getMainLooper()) {
		public void handleMessage(Message msg) {
			Bundle data = msg.getData();
			if (data.getString("Commond").equals("update")) {
				synchronized(mDataThread.mProcessing) {
					byte[] image = data.getByteArray("Image");
					int imageLength = data.getInt("ImageLength");
					Bitmap bmp = BitmapFactory.decodeByteArray(image, 0, imageLength);
		    		mImageView.setImageBitmap(bmp);
				}
			}
		}
	};
	private static final int MY_CUSTOM_DIALOG = 0;
	private void startCustomDialog() { 
		Intent intent = new Intent(this, AddrDialog.class); 
		startActivityForResult(intent, MY_CUSTOM_DIALOG); 
	}

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        mGestureDetector = new MyGestureDetector(this);
        mGestureDetector.setIsLongpressEnabled(false);
        mImageView = (ImageView)findViewById(R.id.imageViewer);
		mImageView.setScaleType(ImageView.ScaleType.CENTER);
		mImageView.setOnTouchListener(this);
		mImageView.setImageResource(R.drawable.play);
    }
    
	@Override
	protected void onPause() {
		if (mStarted == true) {
			mDataThread.stopThread();
			mComThread.stopThread();
			mStarted = false;
		}
		super.onPause();
	}
	@Override
	protected void onResume() {
		mImageView.setImageResource(R.drawable.play);
		super.onResume();
	}
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		this.getMenuInflater().inflate(R.menu.options_menu, menu);
		return true;
	}
	@Override
	public boolean onPrepareOptionsMenu(Menu menu) {
		MenuItem ctrlModeMenu = menu.findItem(R.id.ctrlMenu);
		MenuItem ctrlKBMenu = menu.findItem(R.id.kbMenu);
		ctrlModeMenu.setEnabled(mStarted);
		ctrlKBMenu.setEnabled(mStarted && mCtrlMode);
		if (mCtrlMode) {
			ctrlModeMenu.setTitle("Release Control");
		}
		else {
			ctrlModeMenu.setTitle("Control");
		}
		return super.onPrepareOptionsMenu(menu);
	}
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case R.id.ctrlMenu:
			mCtrlMode =  !mCtrlMode;
			break;
		case R.id.kbMenu:
			InputMethodManager m = (InputMethodManager)getSystemService(INPUT_METHOD_SERVICE);
			m.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);
			break;
		case R.id.aboutMenu:
			Dialog dialog = new AlertDialog.Builder(RemoteViewer.this)
							.setIcon(R.drawable.about)
							.setTitle("About")
							.setMessage(R.string.about_string)
							.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
			                    public void onClick(DialogInterface dialog, int whichButton) {
			                    }
			                })
			                .create();
			dialog.show();
			break;
	    default:
	        return super.onOptionsItemSelected(item);
		}
		return true;
	}
	@Override
	public boolean onKeyUp(int keyCode, KeyEvent event) {
		KeyMap keyMap = new KeyMap();
		Integer key = keyMap.getMap().get(keyCode);
		if (mCtrlMode && key != null) {
			Message msg = mComThread.mHandler.obtainMessage();
			Bundle data = new Bundle();
			data.putString("Commond", "press"); 
			data.putInt("Code", key);
			msg.setData(data);
			mComThread.mHandler.sendMessage(msg);
		}
		return super.onKeyUp(keyCode, event);
	}
	private void start(String ipAddr) {
		mViewWidth = mImageView.getWidth();
		mViewHeight = mImageView.getHeight();
		
		mComThread = new CommondThread(ipAddr);
		mComThread.start();
		
		mDataThread = new DataThread(ipAddr, mHandler);
		mDataThread.start();
		
		Message msg = mComThread.mHandler.obtainMessage();
		Bundle data = new Bundle();
		data.putString("Commond", "set_size");
		data.putInt("Width", mViewWidth);
		data.putInt("Height", mViewHeight);
		msg.setData(data);
		mComThread.mHandler.sendMessage(msg);
	}
	@Override
	public boolean onDown(MotionEvent e) {
		if (mStarted == true) {
			mMoveCount = 0;
		}
		else {
			startCustomDialog();
		}
		/*if (e.getPointerCount() == 2) {
			Log.e("", "onSecondDown");
			return true;
		}*/
		
        return true;
	}
	@Override
	public void onActivityResult(int requestCode, int resultCode, Intent data) { 
        super.onActivityResult(requestCode, resultCode, data); 
        switch(requestCode) { 
        	case MY_CUSTOM_DIALOG:
        		if (resultCode == Activity.RESULT_OK) { 
					String ipAddr = data.getStringExtra(AddrDialog.SEARCH_QUERY_RESULT_FROM_DIALOG);
					if (mStarted != true) {
						mStarted = true;
						start(ipAddr);
					}
        		}
        		else {
        			finish();
        		}
        		break; 
        } 
	}
	@Override
	public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
			float distanceY) {
		if (mStarted == true) {
			mMoveCount++;
			mPosX += distanceX;
			mPosY += distanceY;
			Message msg = mComThread.mHandler.obtainMessage();
			Bundle data = new Bundle();
			if (mDowned) {
				data.putString("Commond", "move");
				data.putInt("x", (int)e2.getX());
				data.putInt("y", (int)e2.getY());
			}
			else {
				data.putString("Commond", "set_pos");
				data.putInt("x", mPosX);
				data.putInt("y", mPosY);
			}
			msg.setData(data);
			mComThread.mHandler.sendMessage(msg);
		}
		
		return true;
	}
	@Override
	public void onShowPress(MotionEvent e) {
		if (mCtrlMode) {
			mDowned = true;
			Message msg = mComThread.mHandler.obtainMessage();
			Bundle data = new Bundle();
			data.putString("Commond", "down");
			data.putInt("x", (int)e.getX());
			data.putInt("y", (int)e.getY());
			msg.setData(data);
			mComThread.mHandler.sendMessage(msg);
		}
	}
	@Override
	public boolean onSingleTapUp(MotionEvent e) {
		if (mCtrlMode && (mDowned || mMoveCount == 0)) {
			Message msg = mComThread.mHandler.obtainMessage();
			Bundle data = new Bundle();
			if (mDowned == true)
				data.putString("Commond", "up");
			else if (mMoveCount == 0)
				data.putString("Commond", "click");
			mDowned = false;
			data.putInt("x", (int)e.getX());
			data.putInt("y", (int)e.getY());
			msg.setData(data);
			mComThread.mHandler.sendMessage(msg);
		}
		return true;
	}
	@Override
	public boolean onMultiScroll(MotionEvent e1, MotionEvent e2) {
		return true;
	}
	@Override
	public boolean onTouch(View v, MotionEvent event) {
		return mGestureDetector.onTouchEvent(event);
	}
	@Override
	public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
			float velocityY) {
        return true;
	}
	@Override
	public void onLongPress(MotionEvent e) {
	}
}